package com.bottle.android_mvi.ui.view

import android.os.Bundle
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.viewbinding.ViewBinding
import com.bottle.android_mvi.domain.viewmodel.BaseMVIViewModel
import com.bottle.lib_core.ui.view.BaseBingActivity

/**
 * 基础AppCompatActivity类，提供ViewBinding和ViewModel的绑定和处理机制
 * @param VB ViewBinding类型
 * @param VM 基础ViewModel类型，支持泛型参数
 */
abstract class BaseMVIActivity<VB : ViewBinding, VM : BaseMVIViewModel<*, *, *>> : BaseBingActivity<VB>(){
    // 抽象属性，用于获取ViewModel实例
    protected abstract val vm: VM

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 观察ViewModel的状态或事件变化，以便在数据变化时及时更新UI
        observeStateOrEvent(vm)
        // 将活动的生命周期与视图绑定对象的生命周期绑定，确保在活动生命周期变化时正确处理视图状态
        bindingLifecycle(lifecycle)
    }

    /**
     * 观察视图模型的状态或事件。
     * 该抽象方法用于在子类中实现对视图模型的状态或事件的观察逻辑。
     *
     * @param viewModel 视图模型实例，包含需要观察的状态或事件。
     */
    abstract fun observeStateOrEvent(viewModel: VM)

    /**
     * 绑定生命周期观察者到指定的生命周期
     *
     * 该方法遍历当前实例的所有字段，寻找那些标记为LifecycleObserver的字段，
     * 并将它们作为观察者添加到给定的生命周期（Lifecycle）中这样做的目的是为了
     * 确保当生命周期状态发生变化时，这些观察者可以得到通知并执行相应的逻辑
     *
     * @param lifecycle 要绑定观察者的生命周期对象通过这个参数，方法知道将哪些观察者
     *                  添加到哪个生命周期对象上
     */
    private fun bindingLifecycle(lifecycle: Lifecycle) {
        // BaseRenderer必须是公共的，`getFields()`提高性能
        for (field in this::class.java.fields) {
            val value = field.get(this)
            if (value is LifecycleObserver) {
                lifecycle.addObserver(value)
            }
        }
    }

}